#!/usr/bin/env python3

#==============================================================================
# Functionality
#==============================================================================
import pdb
import sys
import os
import re
import natsort

from moviepy.editor import *
from PIL import Image
import glob

# utility funcs, classes, etc go here.

def asserting(cond):
    if not cond:
        pdb.set_trace()
    assert(cond)

def has_stdin():
    return not sys.stdin.isatty()

def reg(pat, flags=0):
    return re.compile(pat, re.VERBOSE | flags)

#==============================================================================
# Cmdline
#==============================================================================
import argparse

parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, 
    description="""
TODO
""")
     
parser.add_argument('-v', '--verbose',
    action="store_true",
    help="verbose output" )
     
parser.add_argument('-n', '--no-loop',
    action="store_true",
    help="verbose output" )
     
parser.add_argument('-m', '--mirror',
    action="store_true",
    help="verbose output" )
     
parser.add_argument('fps', type=float)
parser.add_argument('outfile')

args = None

#==============================================================================
# Main
#==============================================================================

def run():
    if len(args.args) <= 0 and not has_stdin():
        # if there were no args and there was no input, prompt user.
        print('Enter input (press Ctrl-D when done):')
    if len(args.args) <= 0 or has_stdin():
        indata = sys.stdin.read()
        paths = indata.splitlines()
    else:
        paths = args.args
    if args.verbose:
        from pprint import pprint as pp
        pp(args)
        pp(paths)

    def get(i):
      return Image.open(i)
      return Image.open(i).resize([128,128])

    # Create the frames
    frames = []
    imgs = []
    for path in paths:
      for f in natsort.natsorted(glob.glob(path)):
        imgs.append(f)
    if args.outfile.endswith('mp4'):
      for i in imgs:
        new_frame = i
        frames.append(new_frame)
      if args.mirror:
        fs = imgs[::-1]
        for i in range(10):
          frames.append(fs[0])
        for img in fs:
          frames.append(img)
        for i in range(10):
          frames.append(fs[-1])
      clip = ImageSequenceClip(frames, fps=args.fps)
      clip.write_videofile(args.outfile)
    else:
      for i in imgs:
        new_frame = get(i)
        frames.append(new_frame)
      if args.mirror:
        fs = imgs[::-1]
        for i in range(10):
          frames.append(get(fs[0]).copy())
        for img in fs:
          frames.append(get(img))
        for i in range(10):
          frames.append(get(fs[-1]).copy())
       
      # Save into a GIF file that loops forever
      duration = 24 * len(frames) / args.fps
      frames[0].save(args.outfile, format='GIF',
                     append_images=frames[1:],
                     save_all=True,
                     duration=duration, loop=1 if args.no_loop else 0)

def main():
    try:
        global args
        if not args:
            args, leftovers = parser.parse_known_args()
            args.args = leftovers
        return run()
    except IOError:
        # http://stackoverflow.com/questions/15793886/how-to-avoid-a-broken-pipe-error-when-printing-a-large-amount-of-formatted-data
        try:
            sys.stdout.close()
        except IOError:
            pass
        try:
            sys.stderr.close()
        except IOError:
            pass

if __name__ == "__main__":
    main()

